package com.tianyu.inspection.service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tianyu.inspection.common.component.AppConstants;
import com.tianyu.inspection.common.enums.FileTypeEnum;
import com.tianyu.inspection.common.model.PageModel;
import com.tianyu.inspection.entity.ClientSoftware;
import com.tianyu.inspection.entity.ConstructionUnits;
import com.tianyu.inspection.entity.UploadFile;
import com.tianyu.inspection.entity.model.OperateMo;
import com.tianyu.inspection.entity.model.QueryMo;
import com.tianyu.inspection.entity.vo.ServiceRo;
import com.tianyu.inspection.mapper.*;
import com.tianyu.inspection.service.api.IUploadFileService;
import io.ocs.model.ContentTypeEnum;
import io.ocs.model.OcsSimpleModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**********************************
 * @Author YSW
 * @Description 文件管理服务
 * @Date 2021/1/20 - 15:48
 **********************************/

@Slf4j
@Service
public class UploadFileServiceImpl implements IUploadFileService {

    @Resource
    private ClientSoftwareMapper clientSoftwareMapper;

    @Resource
    private DangerProcessMapper dangerProcessMapper;

    @Resource
    private PileCardMapper pileCardMapper;

    @Resource
    private GeneralFacilitiesMapper generalFacilitiesMapper;

    @Resource
    private ConstructionUnitsMapper constructionUnitsMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private ProjectMapper projectMapper;

    @Resource
    private UploadFileMapper uploadFileMapper;

    @Resource
    private PipelineMapper pipelineMapper;

    @Resource
    private DangerMapper dangerMapper;

    @Resource
    private FlyTaskMapper flyTaskMapper;

    @Resource
    private OcsSimpleModel ocsSimpleModel;

    @Resource
    private AppConstants appConstants;

    @Resource
    private ValueOperations<String, Object> valueOperations;

    @Resource
    HashOperations<String, String, Object> hashOperations;

    @Override
    public JSONObject ocsPutGroupProgress(String modelId) {
        final Map<String, Object> objectMap = hashOperations.entries(appConstants.redisOcsGroupPut + modelId);
        int count = 0;
        int totalSize = 0;
        for (Object o : objectMap.values()) {
            final JSONObject object = JSONObject.from(o);
            if (object.getBoolean("isFinished")) {
                final Integer objSize = object.getInteger("objSize");
                if (objSize != null) {
                    totalSize += objSize;
                }
                count++;
            }
        }
        hashOperations.put(appConstants.redisOcsGroupPutProgress + modelId, "objUploadedCount", count);
        final Object basicInformationId = hashOperations.get(appConstants.redisOcsGroupPutProgress + modelId, "basicInformationId");
        final Object objCount = hashOperations.get(appConstants.redisOcsGroupPutProgress + modelId, "objCount");
        return JSONObject.of("basicInformationId", basicInformationId, "objCount", objCount,
                "objUploadedCount", count,
                "totalSize", totalSize);
    }

    @Override
    public JSONObject ocsPutUrlCacheGet(String modelId) {
        final JSONObject jsonObject = new JSONObject();
        final Map<String, Object> objectMap = hashOperations.entries(appConstants.redisOcsGroupPut + modelId);
        final long currentTimeMillis = System.currentTimeMillis();
        final Map<String, JSONObject> cacheMap = new HashMap<>();
        for (Map.Entry<String, Object> entry : objectMap.entrySet()) {
            final String path = entry.getKey();
            final JSONObject object = JSONObject.from(entry.getValue());
            if (!object.getBoolean("isFinished")) {
                final Long expireEndTime = object.getLong("expireEndTime");
                final String objectPath = object.getString("objPath");
                if (currentTimeMillis - expireEndTime > 0) {
                    jsonObject.put(path, object.getString("objectPutUrl"));
                } else {
                    final String objectPutUrl = ocsSimpleModel.getObjectPutUrl(path,
                            ContentTypeEnum.APPLICATION_OCTET_STREAM.getValue(),
                            3600 * 12L);
                    jsonObject.put(path, objectPutUrl);
                    cacheMap.put(path, JSONObject.of(
                            "objPath", objectPath,
                            "objectPutUrl", objectPutUrl,
                            "expireEndTime", expireEndTime,
                            "isFinished", false));
                }
            }
        }
        if (cacheMap.size() > 0) {
            hashOperations.putAll(appConstants.redisOcsGroupPut + modelId, cacheMap);
        }
        return jsonObject;
    }

    @Override
    public JSONObject ocsPutUrlGet(Integer basicInformationId, String modelId, String pathPrefix, JSONArray objPathForUpload) {
        final JSONObject jsonObject = new JSONObject();
        final long expireEndTime = System.currentTimeMillis() + 3600 * 6L;
        final Map<String, JSONObject> cacheMap = new HashMap<>();
        for (Object o : objPathForUpload) {
            final String path = (String) o;
            final String objectPath = pathPrefix + path;
            final String objectPutUrl = ocsSimpleModel.getObjectPutUrl(objectPath, ContentTypeEnum.APPLICATION_OCTET_STREAM.getValue(), 3600 * 12L);
            jsonObject.put(path, objectPutUrl);
            cacheMap.put(path, JSONObject.of(
                    "objPath", objectPath,
                    "objectPutUrl", objectPutUrl,
                    "expireEndTime", expireEndTime,
                    "isFinished", false));
        }
        hashOperations.putAll(appConstants.redisOcsGroupPut + modelId, cacheMap);
        hashOperations.putAll(appConstants.redisOcsGroupPutProgress + modelId, JSONObject.of(
                "basicInformationId", basicInformationId,
                "objCount", objPathForUpload.size(),
                "objUploadedCount", 0
        ));
        return jsonObject;
    }


    @Override
    public String ocsPutUrlGet(String pathPrefix, String objPathForUpload) {
        return ocsSimpleModel.getObjectGetUrl(pathPrefix + objPathForUpload, 3600 * 12L);
    }

    /**
     * OSS单文件上传
     *
     * @param multipartFile 单文件对象
     * @return 上传地址
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
    public ServiceRo ossUpload(MultipartFile multipartFile, Integer category, Integer projectId, Integer userId) {
        //1MB = 1024 * 1024 字节 = 1048576字节
        long fileMixSize = 1024 * 1024 * 20;
        if (multipartFile.getSize() > fileMixSize && projectId != 1) {
            return new ServiceRo().setResult(false).setMessage("文件大于20MB");
        }
        String originalFilename = multipartFile.getOriginalFilename();
        if (Objects.nonNull(originalFilename)) {
            int lastIndex = originalFilename.lastIndexOf(".");
            String path;
            path = projectId + "/category/" + category + "/" + UUID.randomUUID().toString().substring(0,13);
            path = path + originalFilename.substring(lastIndex);
            try {
                long startTimeMillis = System.currentTimeMillis();
                if (ocsSimpleModel.putObject(path, multipartFile.getInputStream(), multipartFile.getContentType())) {
                    long endTimeMillis = System.currentTimeMillis();
                    log.info("项目[{}] - 用户[{}] 文件[{},类型[{}]],已上传,上传OSS路径[{}],用时[{}ms]", projectId, userId,
                            originalFilename, multipartFile.getContentType(), path, (endTimeMillis - startTimeMillis));
                    UploadFile uploadFile = new UploadFile()
                            .setUrl("/" + path)
                            .setSize(multipartFile.getSize())
                            .setProjectId(projectId)
                            .setType(multipartFile.getContentType())
                            .setCategory(category);
                    uploadFileMapper.insert(uploadFile);
                    return new ServiceRo().setMessage("/" + path);
                } else {
                    return new ServiceRo().setResult(false).setMessage("文件上传失败");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return new ServiceRo().setResult(false).setMessage("文件原名称为空");
    }

    /**
     * OSS多文件上传
     *
     * @param multipartFiles 多文件数组
     * @return 文件地址列表
     */
    @Override
    public List<String> ossUploads(MultipartFile[] multipartFiles, Integer category, Integer projectId, Integer userId) {
        List<String> list = new ArrayList<>();
        try {
            if (multipartFiles != null) {
                for (MultipartFile multipartFile : multipartFiles) {
                    ServiceRo serviceRo = ossUpload(multipartFile, category, projectId, userId);
                    if (serviceRo.getResult()) {
                        list.add(serviceRo.getMessage());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 存储文件清理 -> 遍历文件,
     * 当文件不再被引用,文件在OSS存在,则删除OSS文件 并删除文件表记录,
     * 当文件被引用但文件在OSS被删除,则将文件表该文件记录置状态为不可用
     *
     * @return 文件地址列表
     */
    @Override
    public ModelMap ossCleanUselessly() {
        ModelMap modelMap = new ModelMap();
        QueryWrapper<UploadFile> wrapper = new QueryWrapper<>();
        List<UploadFile> uploadFiles = uploadFileMapper.selectList(wrapper);
        AtomicInteger countDbDelete = new AtomicInteger();
        AtomicInteger countOssDelete = new AtomicInteger();
        AtomicInteger countUsedNonExistent = new AtomicInteger();
        uploadFiles.forEach(uploadFile -> {
            Integer category = uploadFile.getCategory();
            Integer fileId = uploadFile.getId();
            String url = uploadFile.getUrl().substring(1);
            switch (category) {
                //客户端文件清理
                case 2: {
                    pcClientClean(countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                //管线PB文件清理
                case 3: {
                    clean(pipelineMapper, "points_url", countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                //遥测PB文件清理
                case 4: {
                    clean(flyTaskMapper, "telemetry_url", countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                //险情图片文件清理
                case 5: {
                    clean(dangerMapper, "label_image", countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                //险情处理图片文件清理
                case 6: {
                    clean(dangerProcessMapper, "scene_image", countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                //桩牌图片文件清理
                case 7: {
                    clean(pileCardMapper, "scene_image", countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                //阀室图片文件清理
                case 8: {
                    clean(generalFacilitiesMapper, "scene_image", countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                //施工单位图片文件清理
                case 9: {
                    constructionUnitClean(countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                //用户头像图片文件清理
                case 10: {
                    clean(userMapper, "avatar_url", countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                //客户端Logo图片文件清理
                case 11: {
                    clean(projectMapper, "client_logo", countDbDelete, countOssDelete, countUsedNonExistent, uploadFile, fileId, url);
                }
                break;
                default: {
                }
            }
        });
        modelMap.addAttribute("usedNonExistentSetStatus", countUsedNonExistent);
        modelMap.addAttribute("unusedOssDeleteCount", countOssDelete);
        modelMap.addAttribute("unusedDbDeleteCount", countDbDelete);
        return modelMap;
    }

    private <T> void clean(BaseMapper<T> baseMapper, String pathColumn, AtomicInteger countDbDelete, AtomicInteger countOssDelete, AtomicInteger countUsedNonExistent, UploadFile uploadFile, Integer fileId, String url) {
        if (0 == baseMapper.selectCount(new QueryWrapper<T>().eq(pathColumn, "/" + url))) {
            if (ocsSimpleModel.deleteObject(url)) {
                countOssDelete.incrementAndGet();
            }
            if (1 == uploadFileMapper.deleteById(fileId)) {
                countDbDelete.incrementAndGet();
            }
        } else {
            if (!ocsSimpleModel.isObjectExist(url)) {
                if (uploadFile.getState() == 0) {
                    uploadFile.setState(1);
                    if (0 != uploadFileMapper.updateById(uploadFile)) {
                        countUsedNonExistent.incrementAndGet();
                    }
                }
            }
        }
    }

    private <T> void pcClientClean(AtomicInteger countDbDelete, AtomicInteger countOssDelete, AtomicInteger countUsedNonExistent, UploadFile uploadFile, Integer fileId, String url) {
        if (0 == clientSoftwareMapper.selectCount(new QueryWrapper<ClientSoftware>()
                .eq("url", "/" + url).or().eq("full_url", "/" + url))) {
            if (ocsSimpleModel.deleteObject(url)) {
                countOssDelete.incrementAndGet();
            }
            if (1 == uploadFileMapper.deleteById(fileId)) {
                countDbDelete.incrementAndGet();
            }
        } else {
            if (!ocsSimpleModel.isObjectExist(url)) {
                if (uploadFile.getState() == 0) {
                    uploadFile.setState(1);
                    if (0 != uploadFileMapper.updateById(uploadFile)) {
                        countUsedNonExistent.incrementAndGet();
                    }
                }
            }
        }
    }

    private <T> void constructionUnitClean(AtomicInteger countDbDelete, AtomicInteger countOssDelete, AtomicInteger countUsedNonExistent, UploadFile uploadFile, Integer fileId, String url) {
        if (0 == constructionUnitsMapper.selectCount(new QueryWrapper<ConstructionUnits>()
                .eq("scene_image", "/" + url).or().eq("safe_area_image", "/" + url))) {
            if (ocsSimpleModel.deleteObject(url)) {
                countOssDelete.incrementAndGet();
            }
            if (1 == uploadFileMapper.deleteById(fileId)) {
                countDbDelete.incrementAndGet();
            }
        } else {
            if (!ocsSimpleModel.isObjectExist(url)) {
                if (uploadFile.getState() == 0) {
                    uploadFile.setState(1);
                    if (0 != uploadFileMapper.updateById(uploadFile)) {
                        countUsedNonExistent.incrementAndGet();
                    }
                }
            }
        }
    }


    @Override
//    @Scheduled(cron = "0 0 0 * * ?")
    public void fileStatisticalAnalysisScheduled() {
        ModelMap modelMap = fileStatisticalAnalysis();
        valueOperations.set(appConstants.redisFileAnalyse, modelMap, 7, TimeUnit.DAYS);
    }

    /**
     * 存储文件分析
     *
     * @return 文件地址列表
     */
    @Override
    public ModelMap fileStatisticalAnalysis() {
        ModelMap modelMap = new ModelMap();
        List<UploadFile> uploadFiles = uploadFileMapper.selectList(new QueryWrapper<>());
        AtomicInteger unusedTotal = new AtomicInteger();
        AtomicInteger usedExistentTotal = new AtomicInteger();
        AtomicInteger usedNonExistentTotal = new AtomicInteger();
        HashMap<String, HashMap<String, AtomicInteger>> statisticalMap = new HashMap<>(10);
        uploadFiles.forEach(uploadFile -> {
            Integer category = uploadFile.getCategory();
            String url = uploadFile.getUrl().substring(1);
            switch (category) {
                case 1: {
                    HashMap<String, AtomicInteger> map = statisticalMap.get("relevant");
                    if (Objects.isNull(map)) {
                        map = new HashMap<>(4);
                        map.put("total", new AtomicInteger(Math.toIntExact(uploadFileMapper.selectCount(new QueryWrapper<UploadFile>().eq("category", 1)))));
                        map.put("unused", new AtomicInteger(0));
                        map.put("available", new AtomicInteger(0));
                        map.put("usedNonExistent", new AtomicInteger(0));
                        statisticalMap.put("relevant", map);
                    }
                    usedExistentTotal.incrementAndGet();
                    map.get("available").incrementAndGet();
                }
                break;
                //客户端文件统计
                case 2: {
                    statisticUrl(clientSoftwareMapper, "url",
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "clientSoftware");
                }
                break;
                //管线PB文件统计
                case 3: {
                    statisticUrl(pipelineMapper, "points_url",
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "pipeline");
                }
                break;
                //遥测PB文件统计
                case 4: {
                    statisticUrl(flyTaskMapper, "telemetry_url",
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "flyTask");
                }
                break;
                //险情图片文件统计
                case 5: {
                    statisticUrl(dangerMapper, "label_image",
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "danger");
                }
                break;
                //险情处理图片文件统计
                case 6: {
                    statisticUrl(dangerProcessMapper, "scene_image",
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "dangerProcess");
                }
                break;
                //桩牌图片文件统计
                case 7: {
                    statisticUrl(pileCardMapper, "scene_image",
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "pileCard");
                }
                break;
                //阀室图片文件统计
                case 8: {
                    statisticUrl(generalFacilitiesMapper, "scene_image",
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "valueChest");
                }
                break;
                //施工单位图片文件统计
                case 9: {
                    constructionUnitsStatisticUrl(constructionUnitsMapper,
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "constructionUnits");
                }
                break;
                //用户头像图片文件统计
                case 10: {
                    statisticUrl(userMapper, "avatar_url",
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "user");
                }
                break;
                //客户端Logo图片文件统计
                case 11: {
                    statisticUrl(projectMapper, "client_logo",
                            unusedTotal, usedExistentTotal, usedNonExistentTotal,
                            statisticalMap, category, url, "clientLogo");
                }
                break;
                default: {
                }
            }
        });
        Integer allCount = Math.toIntExact(uploadFileMapper.selectCount(new QueryWrapper<>()));
        modelMap.put("total", allCount);
        modelMap.put("unused", unusedTotal.get());
        modelMap.put("available", usedExistentTotal);
        modelMap.put("usedNonExistent", usedNonExistentTotal);
        modelMap.put("category", statisticalMap);
        return modelMap;
    }

    private <T> void statisticUrl(BaseMapper<T> mapper, String column, AtomicInteger unusedTotal, AtomicInteger usedExistentTotal, AtomicInteger usedNonExistentTotal, HashMap<String, HashMap<String, AtomicInteger>> statisticalMap, Integer category, String url, String key) {
        HashMap<String, AtomicInteger> map = statisticalMap.get(key);
        if (Objects.isNull(map)) {
            map = new HashMap<>(4);
            map.put("total", new AtomicInteger(Math.toIntExact(uploadFileMapper.selectCount(new QueryWrapper<UploadFile>().eq("category", category)))));
            map.put("unused", new AtomicInteger(0));
            map.put("available", new AtomicInteger(0));
            map.put("usedNonExistent", new AtomicInteger(0));
            statisticalMap.put(key, map);
        }
        if (0 != mapper.selectCount(new QueryWrapper<T>().eq(column, "/" + url))) {
            if ((ocsSimpleModel.isObjectExist(url))) {
                usedExistentTotal.incrementAndGet();
                map.get("available").incrementAndGet();
            } else {
                usedNonExistentTotal.incrementAndGet();
                map.get("usedNonExistent").incrementAndGet();
            }
        } else {
            unusedTotal.incrementAndGet();
            map.get("unused").incrementAndGet();
        }
    }

    private <T> void constructionUnitsStatisticUrl(BaseMapper<T> mapper, AtomicInteger unusedTotal, AtomicInteger usedExistentTotal, AtomicInteger usedNonExistentTotal, HashMap<String, HashMap<String, AtomicInteger>> statisticalMap, Integer category, String url, String key) {
        HashMap<String, AtomicInteger> map = statisticalMap.get(key);
        if (Objects.isNull(map)) {
            map = new HashMap<>(4);
            map.put("total", new AtomicInteger(Math.toIntExact(uploadFileMapper.selectCount(new QueryWrapper<UploadFile>().eq("category", category)))));
            map.put("unused", new AtomicInteger(0));
            map.put("available", new AtomicInteger(0));
            map.put("usedNonExistent", new AtomicInteger(0));
            statisticalMap.put(key, map);
        }
        if (0 != mapper.selectCount(new QueryWrapper<T>().eq("scene_image", "/" + url).or().eq("safe_area_image", "/" + url))) {
            if ((ocsSimpleModel.isObjectExist(url))) {
                usedExistentTotal.incrementAndGet();
                map.get("available").incrementAndGet();
            } else {
                usedNonExistentTotal.incrementAndGet();
                map.get("usedNonExistent").incrementAndGet();
            }
        } else {
            unusedTotal.incrementAndGet();
            map.get("unused").incrementAndGet();
        }
    }

    /**
     * 分页查询
     *
     * @param queryMo 参数模型
     * @return ModelMap
     */
    @Override
    public IPage<UploadFile> searchListPage(QueryMo queryMo) {
        IPage<UploadFile> modelPage = PageModel.getModelPage(queryMo, uploadFileMapper);
        modelPage.getRecords().forEach(uploadFile -> {
            String url = uploadFile.getUrl();
            if (Objects.nonNull(url)) {
                uploadFile.setUrl(ocsSimpleModel.getObjectUrl(url));
            }
        });
        return modelPage;
    }

    /**
     * 通过ID等参数查询一条数据
     *
     * @param queryMo 参数集[实体ID 与 项目ID, 数据状态等]
     * @return 单条记录结果
     */
    @Override
    public UploadFile selectOne(QueryMo queryMo) {
        if (Objects.nonNull(queryMo.getEqMap().get("id"))) {
            UploadFile uploadFile = uploadFileMapper.selectOne(new QueryWrapper<UploadFile>().allEq(queryMo.getEqMap()));
            if (Objects.nonNull(uploadFile)) {
                String url = uploadFile.getUrl();
                if (Objects.nonNull(url)) {
                    uploadFile.setUrl(ocsSimpleModel.getObjectUrl(url));
                }
            }
            return uploadFile;
        }
        return null;
    }

    /**
     * 插入一条数据
     *
     * @param operateMo 实体对象
     * @return 是否操作成功
     */
    @Override
    public boolean insert(OperateMo operateMo) {
        ObjectMapper objectMapper = new ObjectMapper();
        UploadFile uploadFile = objectMapper.convertValue(operateMo.getEntity(), UploadFile.class);
        return 1 == uploadFileMapper.insert(uploadFile);
    }

    /**
     * 通过ID删除一条数据
     *
     * @param queryMo 参数集[实体ID 与 项目ID, 数据状态等]
     * @return 是否操作成功
     */
    @Override
    public boolean delete(QueryMo queryMo) {
        if (Objects.nonNull(queryMo.getEqMap().get("id"))) {
            return 1 == uploadFileMapper.delete(new QueryWrapper<UploadFile>().allEq(queryMo.getEqMap()));
        }
        return false;
    }

    /**
     * 插入一条数据
     *
     * @param operateMo 更新参数集
     * @return ModelMap
     */
    @Override
    public boolean update(OperateMo operateMo) {
        ObjectMapper objectMapper = new ObjectMapper();
        UploadFile uploadFile = objectMapper.convertValue(operateMo.getEntity(), UploadFile.class);
        return 1 == uploadFileMapper.update(uploadFile, new QueryWrapper<UploadFile>().allEq(operateMo.getEqMap()));
    }

    /**
     * 通过ID逻辑删除一条数据
     *
     * @param queryMo 参数集[实体ID 与 项目ID, 数据状态]
     * @return 是否操作成功
     */
    @Override
    public boolean logicallyDelete(QueryMo queryMo) {
        return 1 == uploadFileMapper.update(
                new UploadFile().setState(1),
                new QueryWrapper<UploadFile>().allEq(queryMo.getEqMap())
        );
    }
}
